// assets/test/imageGenerator.ts
import { Texture2D, SpriteFrame, ImageAsset } from 'cc';
import { PatternConfig } from './pattern-config';

export type VariationIntensity = 'subtle' | 'medium' | 'strong';

function getPixelVariation(
  logicX: number,
  logicY: number,
  baseColor: [number, number, number, number],
  intensity: VariationIntensity = 'medium'
): [number, number, number, number] {
  const subtle = [0.92, 0.97, 1.0, 1.03, 1.08];
  const medium = [0.85, 0.93, 1.0, 1.07, 1.15];
  const strong = [0.7, 0.85, 1.0, 1.15, 1.3];
  const table = intensity === 'strong' ? strong : intensity === 'subtle' ? subtle : medium;
  const k = table[(logicX + logicY) % table.length];
  const r = Math.max(0, Math.min(255, Math.round(baseColor[0] * k)));
  const g = Math.max(0, Math.min(255, Math.round(baseColor[1] * k)));
  const b = Math.max(0, Math.min(255, Math.round(baseColor[2] * k)));
  return [r, g, b, baseColor[3]];
}

export function generatePixelData(
  config: PatternConfig,
  enableColorVariation: boolean = true,
  variationIntensity: VariationIntensity = 'medium'
): { pixelData: Uint8Array; width: number; height: number } {
  const { pattern, pixelSize, pixelColor, backgroundColor } = config;
  const patternHeight = pattern.length;
  const patternWidth = pattern[0].length;
  const width = patternWidth * pixelSize;
  const height = patternHeight * pixelSize;
  const pixelData = new Uint8Array(width * height * 4);

  const logicPixelColors: [number, number, number, number][][] = [];
  for (let y = 0; y < patternHeight; y++) {
    logicPixelColors[y] = [];
    for (let x = 0; x < patternWidth; x++) {
      if (pattern[y][x] === 1) {
        logicPixelColors[y][x] = enableColorVariation
          ? getPixelVariation(x, y, pixelColor, variationIntensity)
          : pixelColor;
      } else {
        logicPixelColors[y][x] = backgroundColor;
      }
    }
  }

  for (let ly = 0; ly < patternHeight; ly++) {
    for (let lx = 0; lx < patternWidth; lx++) {
      const color = logicPixelColors[ly][lx];
      const startX = lx * pixelSize;
      const startY = ly * pixelSize;
      const endX = startX + pixelSize;
      const endY = startY + pixelSize;
      for (let y = startY; y < endY; y++) {
        for (let x = startX; x < endX; x++) {
          const idx = (y * width + x) * 4;
          const r = (Math.random() * 256) | 0;
          const g = (Math.random() * 256) | 0;
          const b = (Math.random() * 256) | 0;
          pixelData[idx] = color[0];
          pixelData[idx + 1] = color[1];
          pixelData[idx + 2] = color[2];
          pixelData[idx + 3] = color[3];
        }
      }
    }
  }

  return { pixelData, width, height };
}

// export function createSpriteFrameFromBufferData(
//   pixelData: Uint8Array,
//   width: number,
//   height: number
// ): {spriteFrame:SpriteFrame,texture:Texture2D} {
//   const texture = new Texture2D();
//   texture.image = new ImageAsset({
//     width,
//     height,
//     format: Texture2D.PixelFormat.RGBA8888,
//     _data: pixelData,
//     _compressed: false,
//   });

//   const spriteFrame = new SpriteFrame();
//   spriteFrame.texture = texture;
//   spriteFrame.packable = false;
//   return {spriteFrame,texture};
// }

export function createSpriteFrameFromPixelData(
  pixelData: Uint8Array,
  width: number,
  height: number
): {spriteFrame:SpriteFrame,texture:Texture2D} {
  // const expected = width * height * 4;
  // if (pixelData.length !== expected) {
  //   if (pixelData.length < expected) {
  //     const fixed = new Uint8Array(expected);
  //     fixed.set(pixelData.subarray(0, pixelData.length), 0);
  //     pixelData = fixed;
  //   } else {
  //     pixelData = pixelData.subarray(0, expected);
  //   }
  // }
  const texture = new Texture2D();
  texture.image = new ImageAsset({
    width,
    height,
    format: Texture2D.PixelFormat.RGBA8888,
    _data: pixelData,
    _compressed: false,
  });

  const spriteFrame = new SpriteFrame();
  spriteFrame.texture = texture;
  spriteFrame.packable = false;
  return {spriteFrame,texture};
}